<template>
  <div class="commonswiper" :style="{width: count * width + 'px'}">
    <ul
      :style="{transitionDuration, width: idata.length * width + 'px', marginLeft: marginLeft + 'px'}"
    >
      <li :style="{width: width + 'px'}" v-for="(item, index) in idata" :key="index">
        <!-- 把这条记录的数据传给插槽 -->
        <slot :data="item" />
      </li>
    </ul>
    <template v-if="!nobtns">
      <div @click="left" class="leftbtn"><</div>
      <div @click="right" class="rightbtn">></div>
    </template>
  </div>
</template>

<script>
export default {
  props: {
    // 每个格子中的原始数据
    data: {
      type: Array,
      default: function() {
        return [];
      }
    },
    // 滚动的时间间隔
    interval: {
      type: Number,
      default: 4000
    },
    // 每次显示几张图片
    count: {
      type: Number,
      default: 1
    },
    // 每个格子的宽度
    width: {
      type: Number,
      default: 200
    },
    // 是否自动滚动
    auto: {
      type: Boolean,
      default: false
    },
    // 是否有左右两个按钮
    nobtns: {
      type: Boolean,
      default: false
    },
    // 是否持续滚动
    moving: {
      type: Boolean,
      default: false
    },
    // 是否暂停
    stop: {
      type: Boolean,
      default: false
    },
    // 拖拽条的值
    dragValue: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      timer: null, // 定时器
      // 如果正在移动中就去掉 动画效果
      transitionDuration: this.moving ? "0s" : "0.5s",
      marginLeft: -this.count * this.width // 初始位置，去掉前面多余格式的值
    };
  },
  // 监听
  watch: {
    // 从父组件传来的 拖拽条 移动的百分比 在dragvalue值改变时调用
    // 参数一、改变之后的值
    // 参数二、改变之前的值
    dragValue: function(newValue, oldValue) {
      // 修改滚动的位置百分比的位置公式：（结束的坐标-开始的坐标）*百分比+开始坐标
      // this.marginLeft =
      //   (-this.data.length * this.width -
      //     this.count * this.width +
      //     this.count * this.width) *
      //     (this.dragValue / 100) -
      //   this.count * this.width;
      this.marginLeft =
        -this.data.length * this.width * (this.dragValue / 100) -
        this.count * this.width;
      // console.log(this.marginLeft);
    }
  },
  // 计算属性（需要处理过之后再使用的数据）
  computed: {
    // 复制了前后格子之后的商品数组
    idata: function() {
      /* 把 data 数组中的前count 个元素复制到后面，后 count 个元素复制到前面，构造成一个新数组 */
      // 1. 先复制数组中的后 count 个元素 一次显示4张 (倒数4张)
      let lastArr = this.data.slice(
        this.data.length - this.count,
        this.data.length
      );
      // 2. 再复制数组中的前 count 个元素
      let firstArr = this.data.slice(0, this.count);
      // 把hn放到 data 数组的前面， 把 qn 放到 data 数组的后面
      return [...lastArr, ...this.data, ...firstArr];
    }
  },
  mounted() {
    // 是否是持续滚动
    if (this.moving) {
      // 下一帧滚动1像素
      // requestAnimationFrame ：注册一个函数，这个函数会在页面下一帧执行
      requestAnimationFrame(this.movingLeft)
      // 使用定时器也可以
      // setInterval(this.movingLeft, 33)
    } else {
      // 是否自动滚动
      if (this.auto) {
        this.timer = setInterval(this.left, this.interval)
      }
    }
  },
  beforeDestroy() {
    // 如果启动了定时器
    if (null !== this.timer) {
      clearInterval(this.timer)
      this.timer = null
    }
  },
  methods: {
    left() {
      // 向左滚动 n 张图片
      this.marginLeft -= this.count * this.width;
      // 判断是否已经滚动到最后的位置
      if (
        this.marginLeft <=
        -this.data.length * this.width - this.count * this.width
      ) {
        // 0.5s 之后再切换
        setTimeout(() => {
          // 先关闭动画效果
          this.transitionDuration = "0s";
          // 切换回原来的位置
          this.marginLeft = -this.count * this.width;
          // 延迟一会儿后再打开动画效果
          setTimeout(() => {
            // 重新启动动画效果
            this.transitionDuration = "0.5s";
          }, 100);
        }, 500);
      }
    },
    right() {
      // 向右滚动 n 张图片
      this.marginLeft += this.count * this.width;
      // 判断是否已经滚动到最开始的位置
      if (this.marginLeft >= 0) {
        // 0.5s 之后再切换
        setTimeout(() => {
          // 先关闭动画效果
          this.transitionDuration = "0s";
          // 切换回原来的位置
          this.marginLeft = -this.count * this.width;
          // 延迟一会儿后再打开动画效果
          setTimeout(() => {
            // 重新启动动画效果
            this.transitionDuration = "0.5s";
          }, 100);
        }, 500);
      }
    },
    // 向左持续滚动
    movingLeft() {
      // 如果不是暂停才减1像素
      if (!this.stop) {
        // 向左滚动 1 像素
        this.marginLeft -= 1;
        // 是否滚动到最后
        if (
          this.marginLeft <=
          -this.data.length * this.width - this.count * this.width
        ) {
          // 切换回原来的位置
          this.marginLeft = -this.count * this.width;
        }
      }
      // requestAnimationFrame：优势：由系统决定回调函数的执行时机。60Hz的刷新频率，那么每次刷新的间隔中会执行一次回调函数，不会引起丢帧，不会卡顿
      // 在下一帧刷新的时候再执行一次
      requestAnimationFrame(this.movingLeft);
    }
  }
};
</script>

<style lang="scss">
.commonswiper {
  position: relative;
  overflow: hidden;
  ul {
    overflow: hidden;
    transition: all;
  }
  li {
    float: left;
    p {
      padding-top: 10px;
    }
  }
  .leftbtn,
  .rightbtn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 30px;
    height: 30px;
    line-height: 30;
    color: #fff;
    text-align: center;
    font-weight: bold;
    background: #000;
    opacity: 0.2;
    cursor: pointer;
  }
  .leftbtn {
    border-top-right-radius: 50%;
    border-bottom-right-radius: 50%;
  }
  .rightbtn {
    right: 0;
    border-top-left-radius: 50%;
    border-bottom-left-radius: 50%;
  }
}
</style>